/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.slidinglayersample.slice;

import com.slidinglayersample.ResourceTable;
import com.slidinglayersample.ScreenUtils;
import com.wunderlist.slidinglayer.SlidingLayer;

import java.io.IOException;
import java.io.InputStream;

import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.window.service.Window;
import ohos.app.Context;
import ohos.bundle.AbilityInfo;
import ohos.global.resource.NotExistException;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.multimodalinput.event.TouchEvent;

public class MainAbilitySlice extends AbilitySlice {
  private SlidingLayer mSlidingLayer;
  private Text swipeText;
  private Button returnButton;
  private Image imageOpen;
  private Image imageClose;
  private Image image;
  private DependentLayout dependentLayout;
  private Text shadowText;
  private DirectionalLayout directionalLayout;
  private String stick;
  private String transformer;
  private boolean enable = false;
  private boolean shadow = false;
  private boolean offset = false;
  private boolean dependChange = false;
  private boolean touch = true;
  private AbilityInfo.DisplayOrientation displayOrientationOne;
  private int heightPixels;
  private int widthPixels;
  private Paint paint;
  private AnimatorValue animatorValue;

  @Override

  public void onStart(Intent intent) {
    super.onStart(intent);
    super.setUIContent(ResourceTable.Layout_ability_main);
    Window window = getWindow();
    RgbColor rgbColor = new RgbColor(0, 121, 107);
    window.setStatusBarColor(rgbColor.asArgbInt());
    window.setNavigationBarColor(Color.BLACK.getValue());
    if (intent != null) {
      stick = intent.getStringParam("stick");
      transformer = intent.getStringParam("transformer");
      enable = intent.getBooleanParam("enable", false);
      shadow = intent.getBooleanParam("shadow", false);
      offset = intent.getBooleanParam("offset", false);
    }
    mSlidingLayer = (SlidingLayer) findComponentById(ResourceTable.Id_sliding_01);
    dependentLayout = (DependentLayout) findComponentById(ResourceTable.Id_depend);
    shadowText = (Text) findComponentById(ResourceTable.Id_shadow_text);
    directionalLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_include_01);
    swipeText = (Text) findComponentById(ResourceTable.Id_swipeText);
    returnButton = (Button) findComponentById(ResourceTable.Id_return_button);
    imageOpen = (Image) findComponentById(ResourceTable.Id_image_open);
    imageClose = (Image) findComponentById(ResourceTable.Id_image_close);
    image = (Image) findComponentById(ResourceTable.Id_image);
    mSlidingLayer.addDepend(dependentLayout, imageClose);
    heightPixels = getScreenHeight(getContext());
    widthPixels = getScreenWidth(getContext());
    initState(heightPixels, widthPixels);
    buttonClick();


  }

  /**
   * Initializes the origin state of the layer
   */
  private void initState(int heightPixels, int widthPixels) {

    try {
      setupSlidingLayerPosition(heightPixels, widthPixels);
    } catch (NotExistException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
    setupSlidingLayerTransform(transformer);
    setupPreviewMode(enable);
    setupShadow(shadow);
    setupLayerOffset(offset, heightPixels, widthPixels);

    mSlidingLayer.dependEvent();
    mSlidingLayer.setNature(heightPixels, widthPixels);
  }

  private void buttonClick() {

    returnButton.setTouchEventListener(new Component.TouchEventListener() {
      @Override
      public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
        int buttonX = returnButton.getWidth();
        int buttonY = returnButton.getHeight();

        switch (touchEvent.getAction()) {
          case TouchEvent.PRIMARY_POINT_DOWN:
            setAnimator(buttonX / 2, buttonY / 2, Color.WHITE, false, "returnButton");
            break;
          case TouchEvent.PRIMARY_POINT_UP:
            setAnimator(buttonX / 2, buttonY / 2, Color.WHITE, true, "returnButton");
            terminateAbility();
            break;
          default:
            break;
        }
        return true;
      }
    });
    imageOpen.setTouchEventListener(new Component.TouchEventListener() {
      @Override
      public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
        AnimatorProperty animatorProperty = new AnimatorProperty();
        animatorProperty.setTarget(imageOpen);
        switch (touchEvent.getAction()) {
          case TouchEvent.PRIMARY_POINT_DOWN:
            animatorProperty
                .scaleYFrom(1.0f).scaleY(0.9f)
                .scaleXFrom(1.0f).scaleX(0.9f);
            animatorProperty.start();
            break;
          case TouchEvent.PRIMARY_POINT_UP:
            animatorProperty
                .scaleYFrom(0.9f).scaleY(1.0f)
                .scaleXFrom(0.9f).scaleX(1.0f);
            animatorProperty.start();
            mSlidingLayer.openLayer(true);
            break;
          default:
            break;
        }
        return true;
      }
    });

  }

  private void setupSlidingLayerPosition(int heightPixels, int widthPixels) throws IOException,
      NotExistException {

    ComponentContainer.LayoutConfig layoutConfig = dependentLayout.getLayoutConfig();
    int textResource;
    PixelMap p;
    InputStream inputStream;
    ImageSource imageSource;

    switch (stick) {
      case "Right":
        textResource = ResourceTable.String_swipe_right_label;
        inputStream = getResourceManager().getResource(ResourceTable.Media_container_rocket_right);
        imageSource = ImageSource.create(inputStream, null);
        p = imageSource.createPixelmap(null);
        dependentLayout.setMarginLeft(widthPixels);
        mSlidingLayer.setStickTo(SlidingLayer.STICK_TO_RIGHT);
        break;
      case "Left":
        textResource = ResourceTable.String_swipe_left_label;
        inputStream = getResourceManager().getResource(ResourceTable.Media_container_rocket_left);
        imageSource = ImageSource.create(inputStream, null);
        p = imageSource.createPixelmap(null);
        dependentLayout.setMarginLeft(-dependentLayout.getWidth());
        mSlidingLayer.setStickTo(SlidingLayer.STICK_TO_LEFT);
        break;
      case "Top":
        textResource = ResourceTable.String_swipe_up_label;
        inputStream = getResourceManager().getResource(ResourceTable.Media_container_rocket);
        imageSource = ImageSource.create(inputStream, null);
        p = imageSource.createPixelmap(null);
        layoutConfig.width = ComponentContainer.LayoutConfig.MATCH_PARENT;
        layoutConfig.height = heightPixels / 2;
        if (widthPixels > heightPixels) {
          layoutConfig.height = (int) (heightPixels * 0.8);
        }
        dependentLayout.setLayoutConfig(layoutConfig);
        dependentLayout.setMarginTop(-layoutConfig.height);
        mSlidingLayer.setStickTo(SlidingLayer.STICK_TO_TOP);
        break;
      default:
        textResource = ResourceTable.String_swipe_down_label;
        inputStream = getResourceManager().getResource(ResourceTable.Media_container_rocket);
        imageSource = ImageSource.create(inputStream, null);
        p = imageSource.createPixelmap(null);
        layoutConfig.width = ComponentContainer.LayoutConfig.MATCH_PARENT;
        layoutConfig.height = heightPixels - directionalLayout.getHeight();
        dependentLayout.setLayoutConfig(layoutConfig);
        dependentLayout.setMarginTop(layoutConfig.height);
        mSlidingLayer.setStickTo(SlidingLayer.STICK_TO_BOTTOM);
    }
    image.setPixelMap(p);
    swipeText.setText(textResource);

  }

  private void setupSlidingLayerTransform(String layerTransform) {
    switch (layerTransform) {
      case "Alpha":
        mSlidingLayer.setTransformer(mSlidingLayer.Transform_TO_ALPHA);
        break;
      case "Rotation":
        mSlidingLayer.setTransformer(mSlidingLayer.Transform_TO_ROTATION);
        break;
      case "Slide":
        mSlidingLayer.setTransformer(mSlidingLayer.Transform_TO_SLIDE);
        break;
      default:
        mSlidingLayer.setTransformer(mSlidingLayer.Transform_TO_NONE);
        break;
    }
  }

  private void setupPreviewMode(boolean enabled) {
    if (enabled) {
      int previewOffset = enabled ? AttrHelper.vp2px(120, getContext()) : -1;
      mSlidingLayer.setPreviewOffsetDistance(previewOffset, enabled, directionalLayout.getHeight());
    }
  }

  private void setupShadow(boolean enabled) {
    int width = dependentLayout.getWidth();
    int height = dependentLayout.getHeight();
    int shadowSize = AttrHelper.vp2px(10, getContext());
    if (enabled) {
      mSlidingLayer.setShadowSize(shadowText, shadowSize, width, height);

    }
  }

  private void setupLayerOffset(boolean enable, int heightPixels, int widthPixels) {
    if (enable) {
      int offset = 0;
      int crosswise = 8;
      int portait = 14;
      if (widthPixels > heightPixels) {
        crosswise = 10;
        portait = 6;
      }
      switch (stick) {
        case "Right":
          offset = widthPixels / crosswise;
          dependentLayout.setMarginLeft(widthPixels - offset);
          break;
        case "Left":
          offset = widthPixels / crosswise;
          dependentLayout.setMarginLeft(-dependentLayout.getWidth() + offset);
          break;
        case "Bottom":
          offset = heightPixels / portait;
          dependentLayout.setMarginTop(heightPixels - directionalLayout.getHeight() - offset);
          break;
        default:
          break;
      }
      mSlidingLayer.addOffset(offset, enable);
    }

  }

  private void changeBackgroundColorTemp(int x, int y,
                                         int radius, Color color, boolean up, String name) {
    Component.DrawTask drawTask = new Component.DrawTask() {
      @Override
      public void onDraw(Component component, Canvas canvas) {
        paint = null;
        paint = new Paint();
        paint.setStyle(Paint.Style.FILL_STYLE);
        paint.setColor(color);
        if (up) {
          paint.setAlpha(0.0f);
        } else {
          paint.setAlpha(0.2f);
        }
        canvas.drawCircle(x, y, radius, paint);
      }
    };
    switch (name) {
      case "returnButton":
        returnButton.addDrawTask(drawTask);
        break;
      default:
        break;
    }
  }

  private void setAnimator(int x, int y, Color color, boolean up, String name) {
    animatorValue = null;
    animatorValue = new AnimatorValue();
    animatorValue.setCurveType(
        Animator.CurveType.CUBIC_BEZIER_EXTREME_DECELERATION);
    animatorValue.setDuration(500);
    if (up) {
      animatorValue.setDelay(500);
    }
    animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
      @Override
      public void onUpdate(AnimatorValue animatorValue, float v) {
        if ("returnButton".equals(name)) {
          int width = AttrHelper.vp2px(25, getContext());
          int radious = 0;
          if (x >= y) {
            radious = y;
          } else {
            radious = x;
          }
          changeBackgroundColorTemp(width, y, (int) (radious * 0.8 * v), color, up, name);
        } else {
          changeBackgroundColorTemp(x, y, (int) (2 * x * v), color, up, name);
        }
      }
    });
    animatorValue.start();
  }

  @Override
  public void onActive() {
    super.onActive();
  }

  @Override
  public void onForeground(Intent intent) {
    super.onForeground(intent);
  }

  @Override
  protected void onOrientationChanged(AbilityInfo.DisplayOrientation displayOrientation) {
    super.onOrientationChanged(displayOrientation);
    heightPixels = getScreenHeight(getContext());
    widthPixels = getScreenWidth(getContext());
    initState(heightPixels, widthPixels);
    mSlidingLayer.setCurrentState(mSlidingLayer.STATE_CLOSED);
  }

  /**
   * 获取屏幕宽
   *
   * @param context c
   * @return int
   */
  public int getScreenWidth(Context context) {
    return context.getResourceManager().getDeviceCapability().width
        * context.getResourceManager().getDeviceCapability().screenDensity
        / 160;
  }

  /**
   * 获取屏幕高
   *
   * @param context c
   * @return int
   */
  public int getScreenHeight(Context context) {
    return context.getResourceManager().getDeviceCapability().height
        * context.getResourceManager().getDeviceCapability().screenDensity
        / 160;
  }

}
